using System;
using System.Data;
using log4net.Core;
using Sedna.Core.Log;

namespace VMI
{
	/// <summary>
	/// Summary description for Log.
	/// </summary>
	public class Log : System.Web.UI.Page
	{
		protected System.Web.UI.WebControls.DropDownList itemCount;
		protected System.Web.UI.WebControls.Button applyButton;
		protected System.Web.UI.WebControls.TextBox sourceFilter;
		protected System.Web.UI.WebControls.TextBox msgContains;
		protected System.Web.UI.WebControls.DropDownList severityLevel;
		protected System.Web.UI.WebControls.CheckBox sourceExcept;
		protected System.Web.UI.WebControls.DataGrid logDataGrid;
	
		private void Page_Load(object sender, System.EventArgs e)
		{
			PrepareData(BuildEventFilter());
		}

		private void PrepareData(IEventFilter filter)
		{
			DataTable table = new DataTable("LogData");
			table.Columns.Add(new DataColumn("TIME", typeof(DateTime)));
			table.Columns.Add(new DataColumn("SOURCE", typeof(String)));
			table.Columns.Add(new DataColumn("SEVERITY", typeof(String)));
			table.Columns.Add(new DataColumn("MESSAGE", typeof(String)));
			table.Columns.Add(new DataColumn("EXCEPTION", typeof(String)));

			int counter = 0;

			int maxCounter = itemCount.SelectedValue=="ALL"?Int32.MaxValue:Int32.Parse(itemCount.SelectedValue);

			foreach(LoggingEvent logEvent in InMemoryAppender.Instance.EventsReversed)
			{
				if(!filter.Accept(logEvent))
				{
					continue;
				}

				table.Rows.Add(new object[]
					{
						logEvent.TimeStamp, 
						logEvent.LoggerName, 
						logEvent.Level.ToString(), 
						logEvent.MessageObject.ToString(),
						logEvent.GetExceptionString(),
					});

				counter++;
				if(counter >= maxCounter)
				{
					break;
				}
			}

			table.AcceptChanges();

			logDataGrid.DataSource = table.DefaultView;
			logDataGrid.DataBind();
		}


		private IEventFilter BuildEventFilter()
		{
			IEventFilter filter = new StubEventFilter();

			if(sourceFilter.Text != null && sourceFilter.Text != string.Empty)
			{
				filter = new SourceFilter(sourceFilter.Text, filter);
			}

			if(severityLevel.SelectedValue != null && severityLevel.SelectedValue != string.Empty)
			{
				filter = new SeverityLevelFilter(severityLevel.SelectedValue, filter);
			}

			return filter;
		}

		protected interface IEventFilter
		{
			bool Accept(LoggingEvent logEvent);
		}

		protected abstract class AbstractEventFilter : IEventFilter
		{
			protected IEventFilter next = new StubEventFilter();

			public virtual bool Accept(LoggingEvent logEvent)
			{
				return true;
			}

			public AbstractEventFilter(IEventFilter next)
			{
				this.next = next;
			}
		}

		protected class StubEventFilter : IEventFilter
		{
			public bool Accept(LoggingEvent logEvent)
			{
				return true;
			}
		}

		protected class SourceFilter : AbstractEventFilter
		{
			private string source;

			public SourceFilter(string source) : this(source, new StubEventFilter())
			{
			}

			public SourceFilter(string source, IEventFilter next) : base(next)
			{
				this.source = source;
			}

			public override bool Accept(LoggingEvent logEvent)
			{
				return (logEvent.LoggerName.IndexOf(source) >= 0) && next.Accept(logEvent);
			}
		}

		protected class SeverityLevelFilter : AbstractEventFilter
		{
			private Level level;

			public SeverityLevelFilter(string levelName) : this(levelName, new StubEventFilter())
			{
			}

			public SeverityLevelFilter(string levelName, IEventFilter next) : base(next)
			{
				switch (levelName)
				{
					case "DEBUG":
						level = Level.Debug;
						break;
					case "INFO":
						level = Level.Info;
						break;
					case "WARN":
						level = Level.Warn;
						break;
					case "ERROR":
						level = Level.Error;
						break;
					case "FATAL":
						level = Level.Fatal;
						break;
					default:
						level = Level.All;
						break;
				}
			}

			public override bool Accept(LoggingEvent logEvent)
			{
				return (level==Level.All || logEvent.Level>=level) && next.Accept(logEvent);
			}
		}


		#region Web Form Designer generated code
		override protected void OnInit(EventArgs e)
		{
			//
			// CODEGEN: This call is required by the ASP.NET Web Form Designer.
			//
			InitializeComponent();
			base.OnInit(e);
		}
		
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{    
			this.Load += new System.EventHandler(this.Page_Load);

		}
		#endregion
	}
}
